package cn.fl.institution.controller;


import cmm.comm.facade.framework.api.ISysCdMapApiService;
import cmm.comm.facade.framework.condition.SysCdMapDQueryCondition;
import cmm.comm.facade.framework.dto.SysCdMapDDTO;
import cmm.mid.core.framework.page.DataResultVO;
import cmm.mid.core.framework.page.KeyValueVO;
import cn.cmm.base.framework.constant.BaseConstant;
import cn.cmm.base.framework.constant.BaseExceptionConstant;
import cn.cmm.base.framework.exception.BaseException;
import cn.cmm.base.framework.logger.eum.LogExceptionEnum;
import cn.cmm.base.framework.utils.*;
import cn.fl.commons.result.ResponseData;
import cn.fl.enums.InsAccResEnum;
import cn.fl.framework.base.constant.WebBaseConstant;
import cn.fl.framework.base.context.CurrentThreadContext;
import cn.fl.framework.constant.DictionaryConstant;
import cn.fl.preloan.IPrjBscInfoApiService;
import cn.fl.preloan.IProjectCstAccInfoApiService;
import cn.fl.preloan.dto.ChangeBusinessInfoRequest;
import cn.fl.preloan.dto.PrjBscInfoDTO;
import cn.fl.preloan.dto.financialinterface.OpenAccountApplyRequest;
import cn.fl.preloan.dto.financialinterface.OpenAccountValidationRequest;
import cn.fl.preloan.dto.prjbscinfo.GetPrjBscInfoByIdRequest;
import cn.fl.preloan.dto.prjcstaccinfo.PrjCstAccInfoDTO;
import cn.fl.preloan.enums.PreloanResultCodeEnum;
import cn.fl.preloan.financialinterface.IFinancialService;
import cn.fl.project.condition.PrjCstAccInfoQueryCondition;
import cn.fl.project.constant.PrjBscInfoConstant;
import cn.fl.project.service.IPrjCstAccInfoService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description: 项目基础信息表 控制层 资管换卡信息
 */
@Controller
@RequestMapping("/institution/insChangeCrad")
public class InsChangeCardController {

	@Autowired
	private IPrjBscInfoApiService prjBscInfoApiService;

	@Autowired
	private IProjectCstAccInfoApiService accInfoApiService;

	@Autowired
	private IFinancialService financialService;

	@Autowired
	private IPrjCstAccInfoService prjCstAccInfoService;

	@Autowired
	private ISysCdMapApiService sysCdMapApiService;

	@RequestMapping(value = "/toCardDetial.do", method = { RequestMethod.GET })
	public ModelAndView toCardDetial(HttpServletRequest request, HttpServletResponse response){
		BaseLogUtils.newLogger("跳转到还款卡详情页面Start,request:{}", JSON.toJSONString(request.getParameterMap())).info();
		String prjId = request.getParameter("prjId");//项目id
		String insCode = request.getParameter("insCode");//机构code
		String accInfoId = request.getParameter("accInfoId");//客户账户信息id
		String detailFlag = request.getParameter("detailFlag");//detailFlag ：1详情   2解绑    3绑卡
		ModelAndView view = new ModelAndView("institution/inschangecard/insCradDetial");
		this.getParams(prjId, insCode, accInfoId, view);
		view.addObject("detailFlag",detailFlag);
		List<KeyValueVO> bankList = this.getBankList(insCode,detailFlag);
		view.addObject("bankList",bankList);
		if (StringUtils.isNotEmpty(detailFlag) && "3".equals(detailFlag)){
			view.addObject("bkCd", "");
			view.addObject("bkNm", "");
		}
		BaseLogUtils.newLogger("跳转到还款卡详情页面End,view:{}", JSON.toJSONString(view)).info();
		return view;
	}


	private void getParams(String prjId, String insCode, String accInfoId, ModelAndView view){
		BaseLogUtils.newLogger("查询项目客户信息Start").info();
		if (StringUtils.isEmpty(prjId) || StringUtils.isEmpty(insCode) || StringUtils.isEmpty(accInfoId)){
			throw new BaseException("项目id、机构code、客户账户id不能为空!");
		}
		GetPrjBscInfoByIdRequest getRequest = new GetPrjBscInfoByIdRequest();
		getRequest.setPrjId(Long.valueOf(prjId));
		getRequest.setOrgCd(CurrentThreadContext.getCurrentOrgCd());
		getRequest.setSysCd(CurrentThreadContext.getCurrentSysCd());
		ResponseData<PrjBscInfoDTO> responseData = prjBscInfoApiService.selectById(getRequest);
		BaseLogUtils.newLogger("查询项目信息End,prjId:{},request:{},response:{}", prjId, JSON.toJSONString(getRequest), JSON.toJSONString(responseData)).info();
		if (null == responseData || !responseData.getCode().equals(ResponseData.SUCCESS_CODE) || null == responseData.getData()){
			throw new BaseException("未查到项目信息，请核实！");
		}
		PrjBscInfoDTO prjBscInfoDTO = responseData.getData();
		view.addObject("lsCntNo",prjBscInfoDTO.getLsCntNo());
		view.addObject("cstNm",prjBscInfoDTO.getCstNm());
		view.addObject("prjId",prjBscInfoDTO.getId());
		view.addObject("cstId",prjBscInfoDTO.getCstId());
		view.addObject("insCode",prjBscInfoDTO.getInsCode());
		view.addObject("accInfoId",accInfoId);
		view.addObject("fundRasInsId",prjBscInfoDTO.getFundRasInsId());
		view.addObject("insCode",prjBscInfoDTO.getInsCode());

		ResponseData<PrjCstAccInfoDTO> accInfoDTO = accInfoApiService.selectById(Long.valueOf(accInfoId));
		BaseLogUtils.newLogger("查询项目客户账户信息End,prjId:{}, request:{},response:{}", prjId, accInfoId, JSON.toJSONString(accInfoDTO)).info();
		if (null == responseData || !responseData.getCode().equals(ResponseData.SUCCESS_CODE) || null == responseData.getData()){
			throw new BaseException("未查到项目客户账户信息，请核实！");
		}
		PrjCstAccInfoDTO data = accInfoDTO.getData();
		view.addObject("accNo",data.getAccNo());
		view.addObject("certNo",data.getCertNo());
		view.addObject("mp",data.getMp());
		view.addObject("bkCd", data.getBkCd());
		view.addObject("bkNm", data.getBkNm());
		String accResCd = "";
		if (PrjBscInfoConstant.PRJ_INS_CODE_YLBANK.equals(insCode) || PrjBscInfoConstant.PRJ_INS_CODE_TIANJINBANK.equals(insCode)){
			if ("0000".equals(data.getAccResCd())){
				accResCd = "已签约";
			} else if ("9999".equals(data.getAccResCd())){
				accResCd = "已解绑";
			} else {
				accResCd = "未签约";
			}
		} else if (PrjBscInfoConstant.PRJ_INS_CODE_ZGCBANK.equals(insCode)){
			if ("1".equals(data.getAccResCd())){
				accResCd = "已签约";
			} else if ("0".equals(data.getAccResCd())){
				accResCd = "已解绑";
			} else {
				accResCd = "未签约";
			}
		}
		view.addObject("accResCd",accResCd);

		BaseLogUtils.newLogger("查询项目客户信息End,view:{}", JSON.toJSONString(view)).info();
	}

	private List<KeyValueVO> getBankList(String insCode,String flag) {
		//查询支持的银行列表
		SysCdMapDQueryCondition cdMapDQC = new SysCdMapDQueryCondition();
		cdMapDQC.setSysCd(WebBaseConstant.SYS_SYS_CD);
		cdMapDQC.setOrgCd(CurrentThreadContext.getCurrentOrgCd());
		cdMapDQC.setmTypCd("M1041");
		cdMapDQC.setTCode(insCode);
		List<SysCdMapDDTO> sysCdMapDList =  this.sysCdMapApiService.searchSysCdMapDWithTargetList(cdMapDQC);
		//当为绑卡时，新增条件
		if (StringUtils.isNotEmpty(flag) && "3".equals(flag) && "tianjinbank".equals(insCode)){
			sysCdMapDList = sysCdMapDList.stream().filter(sysCdMapDDTO -> "1".equals(sysCdMapDDTO.getCodeAttr1())).collect(Collectors.toList());
		}
		List<KeyValueVO> list =  new ArrayList<>();
		if (CollectionUtils.isNotEmpty(sysCdMapDList)) {
			for(SysCdMapDDTO sysCdMapDDTO : sysCdMapDList) {
				KeyValueVO kv = new KeyValueVO();
				kv.setKey(sysCdMapDDTO.getSCode());
				kv.setValue(sysCdMapDDTO.getSCodeNm());
				list.add(kv);
			}
		}
		return list;
	}


	@RequestMapping(value = "/unbindCard.do", method = { RequestMethod.POST })
	@ResponseBody
	public DataResultVO unbindCard(HttpServletRequest request){
		BaseLogUtils.newLogger("资管绑卡申请Start,request:{}", JSON.toJSONString(request.getParameterMap())).info();
		String insCode = request.getParameter("insCode");
		String prjId = request.getParameter("prjId");
		String accInfoId = request.getParameter("accInfoId");
		try {
			if (StringUtils.isEmpty(prjId)){
				throw new BaseException("项目id为空！");
			}
			if (StringUtils.isEmpty(insCode)){
				throw new BaseException("机构code为空！");
			}
			if (StringUtils.isEmpty(accInfoId)){
				throw new BaseException("客户账户id为空！");
			}
			//解绑
			ChangeBusinessInfoRequest changeBusinessInfoRequest = new ChangeBusinessInfoRequest();
			changeBusinessInfoRequest.setChangeTypeCode("cancelAccount");
			changeBusinessInfoRequest.setBizSN(prjId);
			changeBusinessInfoRequest.setInsCode(insCode);
			BaseLogUtils.newLogger("资管业务变更-解绑Start,prjId:{},request:{}", prjId, JSON.toJSONString(changeBusinessInfoRequest)).info();
			ResponseData responseData = financialService.changeBusinessInfo(changeBusinessInfoRequest);
			BaseLogUtils.newLogger("资管业务变更-解绑End,prjId:{},response:{}", prjId, JSON.toJSONString(responseData)).info();
			if (null == responseData){
				return new DataResultVO(BaseConstant.IS_YESNO_NO, "调用贷前服务无返回，请核实！");
			} else {
				if (ResponseData.SUCCESS_CODE.equals(responseData.getCode())){
					//解绑成功，天津银行自定义：绑卡成功0000，解绑9999
					PrjCstAccInfoDTO dto = new PrjCstAccInfoDTO();
					dto.setId(Long.valueOf(accInfoId));
					dto.setAccResCd("9999");
					BaseLogUtils.newLogger("解绑-修改开户结果Start,prjId:{},dto:{}", prjId, JSON.toJSONString(dto)).info();
					ResponseData<Boolean> data = accInfoApiService.modifyById(dto);
					BaseLogUtils.newLogger("解绑-修改开户结果End,prjId:{},data:{}", prjId, JSON.toJSONString(data)).info();
					if (null == data || !ResponseData.SUCCESS_CODE.equals(data.getCode())){
						return new DataResultVO(BaseConstant.IS_YESNO_NO, "解绑成功-修改开户结果失败，请核实!");
					}
					return new DataResultVO(BaseConstant.IS_YESNO_YES, "解绑成功!");
				} else {
					if (StringUtils.isNotEmpty(responseData.getMessage())){
						return new DataResultVO(BaseConstant.IS_YESNO_NO, responseData.getMessage());
					} else {
						return new DataResultVO(BaseConstant.IS_YESNO_NO, "解绑失败!");
					}
				}
			}
		}catch (Exception e) {
			BaseLogUtils.newLogger("资管解绑业务prjId={},currentUserName={}",prjId,CurrentThreadContext.getCurrentUserName()).setThrowable(e).error(LogExceptionEnum.API_CODE_0102);
			return new DataResultVO(BaseConstant.IS_YESNO_NO, "解绑失败，系统异常");
		}
	}


	/**
	 * 获取验证码
	 */
	@RequestMapping(value = "/getVerificationCode.do", method = {RequestMethod.POST})
	@ResponseBody
	public DataResultVO getVerificationCode(HttpServletRequest request) throws BaseException {
		BaseLogUtils.newLogger("获取验证码Start.qc:{}，操作人:{}", JSON.toJSONString(request.getParameterMap()), CurrentThreadContext.getCurrentUserName()).info();
		DataResultVO dataResultVO = new DataResultVO(BaseConstant.IS_YESNO_YES, "四要素校验通过");
		String prjId = request.getParameter("prjId");//项目id
		try {
			// 四要素验证
			PrjCstAccInfoQueryCondition condition = this.getParameter(request);
			BaseLogUtils.newLogger("获取验证码.必填字段校验End.prjId:{},qc:{}", prjId, JSON.toJSONString(condition)).info();

			//获取验证码
			OpenAccountApplyRequest openAccountApplyRequest = new OpenAccountApplyRequest();
			openAccountApplyRequest.setBizSN(prjId);
			openAccountApplyRequest.setInsCode(condition.getInsCode());
			openAccountApplyRequest.setCustomerId(condition.getCstId().toString());
			openAccountApplyRequest.setCustomerName(condition.getCstNm());
			openAccountApplyRequest.setIdCardNo(condition.getCertNo());
			openAccountApplyRequest.setMobilePhone(condition.getMp());
			openAccountApplyRequest.setBankCardNo(condition.getAccNo());
			openAccountApplyRequest.setBankCode(condition.getBkCd());
			openAccountApplyRequest.setBankName(condition.getBkNm());
			BaseLogUtils.newLogger("获取验证码接口Begin：prjId={}, request={}", prjId, JSON.toJSONString(openAccountApplyRequest)).info();
			ResponseData responseData = this.financialService.openAccountApply(openAccountApplyRequest);
			BaseLogUtils.newLogger("获取验证码接口End:prjId={}, response={}", prjId, JSON.toJSONString(responseData)).info();
			if (ResponseData.SUCCESS_CODE.equals(responseData.getCode()) && null != responseData.getData()) {
				String openAccountStatus = (String) responseData.getData();
				if ("SUCCESS".equals(openAccountStatus) || "PROCESSING".equals(openAccountStatus)) {
					dataResultVO.setSuccess(BaseConstant.IS_YESNO_YES);
					dataResultVO.setInfo("验证码已发送至客户手机");
					return dataResultVO;
				}
			}
			//发送验证码失败
			dataResultVO.setSuccess(BaseConstant.IS_YESNO_NO);
			dataResultVO.setInfo("发送验证码失败：" + responseData.getMessage());
		} catch (BaseException ex) {
			dataResultVO.setSuccess(BaseConstant.IS_YESNO_NO);
			dataResultVO.setInfo(ex.getMessage());
			BaseLogUtils.newLogger("getVerificationCode.获取验证码失败,prjId:{},ERROR:{}", prjId, ex.getMessage()).info();
		} catch (Exception ex) {
			dataResultVO.setSuccess(BaseConstant.IS_YESNO_NO);
			dataResultVO.setInfo("获取验证码,系统异常!");
			BaseLogUtils.newLogger("getVerificationCode.获取验证码失败,prjId:{},ERROR:{}", prjId, ex.getMessage()).error(BaseExceptionConstant.INTERFACE_0102);
		}
		BaseLogUtils.newLogger("getVerificationCode.获取验证码End.prjId:{},resultVO:{},操作人:{}", prjId, JSON.toJSONString(dataResultVO), CurrentThreadContext.getCurrentUserName()).info();
		return dataResultVO;
	}


	private PrjCstAccInfoQueryCondition getParameter(HttpServletRequest request){
		BaseLogUtils.newLogger("请求参数组装信息Start：request={}",JSON.toJSONString(request.getParameterMap())).info();
		String cstAccInfoId = request.getParameter("accInfoId");//项目客户信息表id
		String insCode = request.getParameter("insCode");//机构code
		String prjId = request.getParameter("prjId");//项目id
		String cstId = request.getParameter("cstId");//客户id
		String cstNm = request.getParameter("cstNm");//客户姓名
		String accNo = request.getParameter("accNo");//银行账号
		String mp = request.getParameter("mp");//手机号
		String certNo = request.getParameter("certNo");//身份证号
		String bkCd = request.getParameter("bkCd");//银行代码
		String bkNm = request.getParameter("bkNm");//银行名称

		try {
			if (StringUtils.isEmpty(prjId)) {
				throw new BaseException("项目id为空!");
			}
			if (StringUtils.isEmpty(cstAccInfoId)) {
				throw new BaseException("客户账户id为空!");
			}
			if (StringUtils.isEmpty(insCode)) {
				throw new BaseException("资管机构编码为空!");
			}
			if(StringUtils.isEmpty(certNo)){
				throw new BaseException("身份证号为空!");
			}
			if (StringUtils.isEmpty(cstId)) {
				throw new BaseException("客户id为空!");
			}
			if (StringUtils.isEmpty(cstNm)) {
				throw new BaseException("客户名称为空!");
			}
			if (StringUtils.isEmpty(bkNm) || StringUtils.isEmpty(bkCd)) {
				throw new BaseException("开户银行为空!");
			}
			if (StringUtils.isEmpty(accNo)) {
				throw new BaseException("请维护银行卡号!");
			}
			if (StringUtils.isEmpty(mp)) {
				throw new BaseException("请维护银行预留手机号!");
			}
			PrjCstAccInfoQueryCondition condition = new PrjCstAccInfoQueryCondition();
			condition.setId(Long.valueOf(cstAccInfoId));
			condition.setBkCd(bkCd);
			condition.setBkNm(bkNm);
			condition.setPrjId(Long.valueOf(prjId));
			condition.setCstId(Long.valueOf(cstId));
			condition.setInsCode(insCode);
			condition.setCstNm(cstNm);
			condition.setAccNo(accNo.trim());
			condition.setAccNm(cstNm);
			condition.setMp(mp);
			condition.setCertNo(certNo.trim());
			condition.setCertTypCd(DictionaryConstant.CODE_CERT_TYP_CD_0);
			BaseLogUtils.newLogger("请求参数组装信息End：request={}",JSON.toJSONString(condition)).info();
			return condition;
		} catch (BaseException e) {
			BaseLogUtils.newLogger("请求参数组装信息失败！").info();
		}
		return null;
	}

	/**
	 * 确认绑卡
	 */
	@RequestMapping(value = "/exchangeCardSave.do", method = { RequestMethod.POST })
	@ResponseBody
	public Object exchangeCardSave(HttpServletRequest request) throws BaseException {
		BaseLogUtils.newLogger("资管绑卡Start:request={},currentUserName={}",JSON.toJSONString(request.getParameterMap()), CurrentThreadContext.getCurrentUserName()).info();
		String verificationCode = request.getParameter("verificationCode");
		String prjId = request.getParameter("prjId");
		try {
			//1. 组装请求参数
			PrjCstAccInfoQueryCondition condition = this.getParameter(request);
			BaseLogUtils.newLogger("资管绑卡修改项目客户账户信息,condition:" + JSONObject.toJSONString(condition)).info();
			if(null == condition){
				return new DataResultVO(BaseConstant.IS_YESNO_NO, "信息为空，请核实!");
			}
			if (StringUtils.isBlank(verificationCode)) {
				return new DataResultVO(BaseConstant.IS_YESNO_NO, "验证码为空!");
			}

			OpenAccountValidationRequest openRequest = new OpenAccountValidationRequest();
			openRequest.setBizSN(condition.getPrjId().toString());// 业务流水号
			openRequest.setInsCode(condition.getInsCode());// 资管机构编码
			openRequest.setCustomerId(condition.getCstId().toString());// 客户ID
			openRequest.setCustomerName(condition.getCstNm());// 客户名称
			openRequest.setIdCardNo(condition.getCertNo());// 证件号
			openRequest.setMobilePhone(condition.getMp());// 银行预留手机号
			openRequest.setBankCardNo(condition.getAccNo());// 银行卡号
			openRequest.setCheckCode(verificationCode);
			BaseLogUtils.newLogger("资管绑卡请求Start===prjId:{},openRequest:{}", condition.getPrjId(), JSON.toJSONString(openRequest)).info();
			ResponseData responseData = financialService.openAccountValidation(openRequest);
			BaseLogUtils.newLogger("资管绑卡请求End===prjId:{},responseData:{}", condition.getPrjId(), JSON.toJSONString(responseData)).info();
			String msg = StringUtils.isNotEmpty(responseData.getMessage()) ? responseData.getMessage() : "绑卡失败，请稍后重试！";
			if (ResponseData.SUCCESS_CODE.equals(responseData.getCode()) && null != responseData.getData()){
				String openAccountStatus = (String) responseData.getData();
				if ("SUCCESS".equals(openAccountStatus)) {
					PrjCstAccInfoDTO dto = new PrjCstAccInfoDTO();
					dto.setId(condition.getId());
					dto.setAccNo(condition.getAccNo());
					dto.setMp(condition.getMp());
					dto.setBkCd(condition.getBkCd());
					dto.setBkNm(condition.getBkNm());
					dto.setAccResCd(InsAccResEnum.SUCCESS.code);//开户成功
					dto.setMdfTm(new Date());
					dto.setMdfUsrId(CurrentThreadContext.getCurrentUserId());
					dto.setMdfUsrName(CurrentThreadContext.getCurrentUserName());
					BaseLogUtils.newLogger("绑卡成功后修改账户信息Start===prjId:{},vo:{}", condition.getPrjId(), JSON.toJSONString(dto)).info();
					ResponseData<Boolean> data = accInfoApiService.modifyById(dto);
					BaseLogUtils.newLogger("绑卡成功后修改账户信息End===prjId:{},vo:{}", condition.getPrjId(), JSON.toJSONString(data)).info();
					if (null == responseData || !ResponseData.SUCCESS_CODE.equals(responseData.getCode()) || null == responseData.getData()){
						return new DataResultVO(BaseConstant.IS_YESNO_NO,"修改账户失败，请核查！");
					}
					return new DataResultVO(BaseConstant.IS_YESNO_YES,"绑卡成功！");
				} else {
					return new DataResultVO(BaseConstant.IS_YESNO_NO,msg);
				}
			}
			BaseLogUtils.newLogger("绑卡及校验返回dataResultVO=" + msg).info();
			return new DataResultVO(BaseConstant.IS_YESNO_NO,msg);
		} catch (BaseException ex) {
			BaseLogUtils.newLogger("绑卡及四要素校验异常,prjId:" + prjId + ".ERROR:" + ex.getMessage()).info();
			return new DataResultVO(BaseConstant.IS_YESNO_NO, ex.getMessage());
		} catch (Exception e) {
			BaseLogUtils.newLogger("天津银行确认绑卡及四要素校验系统异常prjId={},error={}" ,prjId, e.getMessage()).info();
			return new DataResultVO(BaseConstant.IS_YESNO_NO, "保存失败，系统异常");
		}
	}

}
